home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 2.iso
/
STUTTGART
/
LANG
/
C
/
LIB
/
EXPRO
/
_files
/
_exprodir
/
exprofle._c
< prev
next >
Wrap
Text File
|
1990-06-04
|
6KB
|
198 lines
/*
* exprofle.c
*
* version 1.00, 04-06-1990
*
* execution profiler
*
* copyright Ferdinand Oeinck 1990
*
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "h.swis"
#include "kernel.h"
#include "h.exproasm"
int * funcadr_ptr;
int * count_ptr;
int funccount;
static char * filen;
void myexithandler(void);
void exprofle_init(char * filename)
{
unsigned int * codestart;
unsigned int * codeend;
unsigned int * i;
int fpestart, fpeend;
int len, instr, count = 0;
_kernel_swi_regs regs;
char * modulename;
if (_kernel_hostos() != _kernel_ARTHUR) {
printf("Error: Not running on ARTHUR host OS\n");
exit(1);
}
if (!_kernel_fpavailable()) {
printf("Warning: Execution time profiling not possible.\n");
printf(" No floating point support.\n");
return;
}
regs.r[0] = 12;
regs.r[1] = 0;
regs.r[2] = 0;
while (_kernel_swi(OS_Module, ®s, ®s) == NULL) {
modulename = (char*)(regs.r[3] + *((int *)(regs.r[3] + 0x10)));
if (strcmp(modulename,"FPEmulator") == 0) break;
}
fpestart = regs.r[3];
_kernel_swi(OS_Module, ®s, ®s);
fpeend = regs.r[3];
if ( (filen = malloc(strlen(filename) + 1)) == NULL) {
printf("Warning: Execution time profiling not possible.\n");
printf(" Malloc failed.\n");
return;
}
strcpy(filen, filename);
codestart = exproasm_getstart();
codeend = exproasm_getend();
for (i = codestart; i != codeend; i++) {
instr = *i & 0xffff0000;
if (instr == (unsigned int) 0xff000000) {
len = *i & 0xffff;
if (len >= strlen((char *)i - len)) count++;
}
}
count += 4;
if ((funcadr_ptr = (int *) calloc(count, sizeof(int))) == NULL) {
printf("Warning: Execution time profiling not possible.\n");
printf(" Malloc failed.\n");
free(filen);
return;
}
if ((count_ptr = (int *) calloc(count, sizeof(int))) == NULL) {
printf("Warning: Execution time profiling not possible.\n");
printf(" Malloc failed.\n");
free(funcadr_ptr);
free(filen);
return;
}
funccount = count;
count = 1;
for (i = codestart; i != codeend; i++) {
instr = *i & 0xffff0000;
if (instr == (unsigned int) 0xff000000) {
len = *i & 0xffff;
if (len >= strlen((char *)i - len)) {
funcadr_ptr[count++] = (int) i - len;
}
}
}
funcadr_ptr[count] = (int) codeend;
funcadr_ptr[count + 1] = (int) fpestart;
funcadr_ptr[count + 2] = (int) fpeend;
if (!exproasm_ClaimIntDeviceVector()) {
free(count_ptr);
free(funcadr_ptr);
free(filen);
printf("Warning: Execution time profiling not possible.\n");
printf(" I think this is not RISC_OS 2.00\n");
return;
}
atexit(myexithandler);
}
void myexithandler(void)
{
int i, sumc = 0;
float sum = 0, sump = 0;
FILE *fp;
exproasm_ReleaseIntDeviceVector();
for (i = 0; i < funccount; i++) sum += count_ptr[i];
sum = sum - count_ptr[funccount - 2]; /* substract double counted fp values */
if (sum == 0) sum = 1;
fp = fopen(filen, "w");
fprintf(fp, " nr address function name percentage count\n");
fprintf(fp, "==========================================================================\n");
fprintf(fp, "%4i %8x: %-40s: %6.2f, %7i\n", 0,
funcadr_ptr[1], "lessthan", 100.0 * (float) count_ptr[0] / sum, count_ptr[0]);
sump += (float) 100.0 * (float) count_ptr[0] / sum;
sumc += count_ptr[0];
for (i = 1 ; i < funccount - 3; i++) {
fprintf(fp, "%4i %8x: %-40s: %6.2f, %7i\n", i, funcadr_ptr[i],
(char *)funcadr_ptr[i], 100.0 * (float) count_ptr[i] / sum, count_ptr[i]);
sump += (float) 100.0 * (float) count_ptr[i] / sum;
sumc += count_ptr[i];
}
fprintf(fp, "%4i %8x: %-40s: %6.2f, %7i\n", funccount-3, funcadr_ptr[funccount-3],
"greaterthan", 100.0 * (float) count_ptr[funccount-3] / sum,
count_ptr[funccount-3]);
sump += (float) 100.0 * (float) count_ptr[funccount-3] / sum;
sumc += count_ptr[funccount - 3];
fprintf(fp, "==========================================================================\n");
fprintf(fp, " %6.2f, %7i\n",
sump, sumc);
fprintf(fp, "percentage of time spent in fpemulator\n");
fprintf(fp, "%4i %8x: %-40s: %6.2f, %7i\n", funccount-2, funcadr_ptr[funccount-2],
"fpemulator", 100.0 * (float) count_ptr[funccount-2] / sum,
count_ptr[funccount-2]);
fclose(fp);
free(count_ptr);
free(funcadr_ptr);
free(filen);
}
/* this function is called every 1/100 seconds */
void binsearch(int *adr)
{
/* binary search of address table */
int high = funccount - 1;
int low = 1;
extern int expro_fp_return_address;
if ((int) adr < (int) funcadr_ptr[1]) { ++count_ptr[0]; return; }
if ((int) adr > (int) funcadr_ptr[funccount-2] &&
(int) adr <= (int) funcadr_ptr[funccount-1]) {
++count_ptr[funccount-2]; /* we are in the fpemulator */
adr = (int*) expro_fp_return_address; /* so use that return address */
}
if ((int) adr > (int) funcadr_ptr[funccount-3]) {
++count_ptr[funccount-3];
return;
}
while((high - low) > 1){
int middle = (high + low) / 2;
if ((int)adr > (int)funcadr_ptr[middle] && (int)adr < (int)funcadr_ptr[middle + 1]) {
low = middle;
break;
}
if ((int)adr > (int)funcadr_ptr[middle+1])
low = middle + 1;
else
high = middle;
}
++count_ptr[low];
}